home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1996-06-21 | 10.9 KB | 422 lines | [TEXT/MEDT] |
- IMPLEMENTATION MODULE HighInOut ;
-
- (*
-
- Implementation and Revisions:
- ============================
-
- Author Date Description
- ------ ---- -----------
-
- af 21/09/90 First implementation (DM 2.01,
- MacMETH 2.6+)
- af 02/10/90 curRP and curWP plus redirection
- mechanism added
-
- *)
-
- IMPORT Terminal; (* just for Read, Write, and WriteLn *)
- FROM Conversions IMPORT StringToReal, RealToFixString;
- (* is too complicated to implement here *)
-
- CONST
- EOL = 15C; (* Return on Mac *)
- LF = 12C;
-
- CAN = 30C;
- ESC = 33C;
- HELP = "?";
- BS = 10C;
- BEL = 7C;
- DEL = 177C;
-
-
- VAR
- RandomWriteDisplay: BOOLEAN;
- curGiveHelp: PROC;
- curRP: ReadProc;
- curWP: WriteProc;
- curWLnP: WriteLnProc;
-
- VAR
- readAgainFlag: BOOLEAN;
-
- PROCEDURE Read (VAR ch: CHAR);
- BEGIN
- IF readAgainFlag THEN
- ch := termCH;
- readAgainFlag := FALSE;
- ELSE
- curRP(termCH); ch := termCH;
- END(*IF*);
- Aborted := ch = ESC;
- END Read;
-
- PROCEDURE ReadAgain;
- BEGIN
- readAgainFlag := TRUE;
- END ReadAgain;
-
-
- PROCEDURE Write (ch: CHAR);
- PROCEDURE SysBeep(duration: INTEGER); CODE 0A9C8H;
- BEGIN
- IF ch=BEL THEN
- SysBeep(1);
- ELSE
- curWP(ch);
- END(*IF*);
- END Write;
-
- PROCEDURE WriteLn;
- BEGIN
- curWLnP;
- END WriteLn;
-
-
-
- PROCEDURE ReadString(VAR s: ARRAY OF CHAR);
- VAR
- ch: CHAR;
- i,wrpos: CARDINAL;
- BEGIN (*ReadString*)
- Done:=TRUE;
- REPEAT Read(ch); UNTIL (ch>" ") OR (ch=ESC) OR (ch=CAN);
- wrpos:=0;
- i:=0;
- LOOP
- IF (ch=DEL) OR (ch=BS) THEN
- IF i>0 THEN DEC(i); s[i]:=" " END;
- IF wrpos>0 THEN
- Write(DEL); DEC(wrpos)
- END(*IF*);
- ELSIF (ch=ESC) OR (ch=CAN) OR (ch<" ") THEN
- termCH:=ch; Done:=FALSE; EXIT
- ELSE
- IF i<=HIGH(s) THEN s[i]:=ch END;
- i:=i+1;
- Write(ch); INC(wrpos);
- END(*IF*);
- Read(ch);
- END(*LOOP*);
- IF i<=HIGH(s) THEN s[i]:=0C END;
- END ReadString;
-
- PROCEDURE ReadInt(VAR x: INTEGER);
- VAR i: INTEGER; n: CARDINAL;
- ch: CHAR; neg: BOOLEAN;
- buf: ARRAY [0..9] OF CHAR;
-
- PROCEDURE next;
- BEGIN ch := buf[n]; n := n+1
- END next;
-
- BEGIN
- ReadString(buf); n := 0; next;
- WHILE ch = " " DO next END ;
- IF ch = "-" THEN
- neg := TRUE; next
- ELSE neg := FALSE;
- IF ch = "+" THEN next END
- END ;
- IF ("0" <= ch) & (ch <= "9") THEN
- i := 0; Done := TRUE;
- REPEAT i := 10*i + (ORD(ch) - ORD("0")); next
- UNTIL (ch < "0") OR ("9" < ch);
- Done:= Done AND (ch<=" ");
- IF neg THEN x := -i ELSE x := i END
- ELSE Done:= FALSE
- END;
- END ReadInt;
-
- PROCEDURE ReadReal (VAR x: REAL);
- VAR buf: ARRAY [0..25] OF CHAR;
- BEGIN
- ReadString(buf);
- StringToReal(buf,0,x,Done);
- END ReadReal;
-
-
- PROCEDURE WriteString (s: ARRAY OF CHAR);
- VAR i,n: INTEGER;
- BEGIN
- i:= 0; n:= HIGH(s);
- WHILE (i<=n) AND (s[i]<>0C) DO
- Write(s[i]); INC(i);
- END(*WHILE*);
- END WriteString;
-
-
- PROCEDURE WriteInt(x: LONGINT; n: CARDINAL);
- VAR i: CARDINAL; dig: INTEGER; x0: LONGINT;
- a: ARRAY [0..12] OF CHAR;
- BEGIN
- i := 0; x0 := ABS(x);
- REPEAT
- dig := x0 MOD 10D; dig := dig + 60B;
- a[i] := CHR(dig);
- x0 := x0 DIV 10D; i := i+1
- UNTIL x0 = 0D;
- IF x < 0D THEN a[i] := "-"; i := i+1 END ;
- WHILE n > i DO
- n := n-1; Write(" ")
- END ;
- REPEAT i := i-1; Write(a[i]) UNTIL i = 0
- END WriteInt;
-
- PROCEDURE WriteReal (x: REAL; n,dec: CARDINAL);
- VAR buf: ARRAY [0..80] OF CHAR; VAR dummyOk: BOOLEAN;
- BEGIN
- RealToFixString (x,dec,n,buf,dummyOk); (* should automatically
- convert to exponential representation if number too large *)
- WriteString(buf);
- END WriteReal;
-
-
- PROCEDURE Wait;
- CONST t = "To continue hit a key";
- VAR ch: CHAR;
- BEGIN
- IF RandomWriteDisplay THEN
- (*. IF Row=maxRow THEN (*insert a line*) WriteLn END;
- Write(BEL); moveCursor(maxRow,(maxCol-25(*length of t*)) DIV 2);
- reverseOn; blinkingOn;
- WriteString(t); Write(BS);
- blinkingOff; reverseOff;
- Read(ch); moveCursor(Row,1); eraseToEOL;
- epr:=epr-ScrollUps;
- moveCursor(epr,epc); eraseToEOL; moveCursor(epr,1); .*)
- ELSE
- Terminal.WriteString(t); Terminal.WriteString("… ");
- Read(ch);
- END(*IF RandomWriteDisplay*);
- END Wait;
-
-
- PROCEDURE DefaultGiveHelp;
- CONST t = "no help information available";
- VAR ch: CHAR;
- BEGIN
- IF RandomWriteDisplay THEN
- (*. IF Row=maxRow THEN (*insert a line*) WriteLn END;
- Write(BEL); moveCursor(maxRow,(maxCol-29(*length of t*)) DIV 2);
- reverseOn; blinkingOn;
- WriteString(t); Write(BS);
- blinkingOff; reverseOff;
- Read(ch); moveCursor(Row,1); eraseToEOL;
- epr:=epr-ScrollUps;
- moveCursor(epr,epc); eraseToEOL; moveCursor(epr,1); .*)
- ELSE
- WriteLn;
- WriteString(t);
- WriteLn;
- END(*IF RandomWriteDisplay*);
- END DefaultGiveHelp;
-
- PROCEDURE InstallGiveHelpProc (hp: PROC);
- BEGIN
- curGiveHelp := hp;
- END InstallGiveHelpProc;
-
-
-
- CONST
- askKeyStringLength=3;
-
- TYPE
- askKeyString=ARRAY[0..askKeyStringLength-1] OF CHAR;
-
- VAR
- yes,no: askKeyString;
-
-
- PROCEDURE Ask(question: ARRAY OF CHAR; VAR affirmation: BOOLEAN);
- VAR
- i: CARDINAL;
- s: askKeyString; les: CARDINAL;
- sofarOK: BOOLEAN;
- ch: CHAR;
- BEGIN (*Ask*)
- LOOP
- WriteString(question);
- (* random screen not supported: epr:=Row; epc:=Col; ScrollUps:=0; *)
- Read(termCH);
- IF termCH=EOL THEN
- affirmation:=FALSE; Aborted:=FALSE;
- WriteString(no); EXIT
- ELSE
- ReadAgain;
- ReadString(s); (*s must be terminated by 0C if shorter than HIGH(s)*)
- IF termCH=ESC THEN
- WriteString("<ESC>");
- affirmation:=FALSE;
- Aborted:=TRUE;
- EXIT
- ELSIF termCH=CAN THEN
- WriteString(" - cancelled!"); WriteLn; Wait;
- ELSE
- sofarOK:=TRUE;
- i:=0;
- WHILE (i<=askKeyStringLength-1) AND (s[i]<>0C) DO
- ch:=CAP(s[i]);
- sofarOK:=sofarOK AND ((ch=yes[i]) OR (ch=no[i]));
- INC(i);
- END(*WHILE*);
- les:=i;
- IF sofarOK THEN
- affirmation:=CAP(s[0])="Y";
- FOR i:=les TO askKeyStringLength-1 DO
- IF affirmation
- THEN Write(yes[i])
- ELSE Write(no[i])
- END(*IF*)
- END(*FOR*);
- Aborted:=FALSE;
- EXIT
- ELSE
- Write(BEL);
- WriteString(" --- illegal answer! Try 'y(es)' or 'n(o)'!");
- WriteLn; Wait;
- END(*IF sofarOK*);
- END(*IF termCH=ESC*);
- END(*IF first char entered = EOL*);
- END(*LOOP*);
- END Ask;
-
-
- PROCEDURE PromptForChars(p: ARRAY OF CHAR; chs: ARRAY OF CHAR;
- VAR ch: CHAR);
-
- VAR s: ARRAY [0..2] OF CHAR;
- PROCEDURE InChs(ch: CHAR): BOOLEAN;
- VAR i,n: CARDINAL; q: BOOLEAN;
- BEGIN
- i:=0; n:=HIGH(chs);
- WHILE i<=n DO IF ch=chs[i] THEN RETURN TRUE ELSE INC(i) END END;
- RETURN FALSE;
- END InChs;
-
- BEGIN (*PromptForChars*)
- REPEAT
- WriteString(p);
- (* random screen not supported: epr:=Row; epc:=Col; ScrollUps:=0; *)
- ReadString(s);
- IF NOT Done THEN
- IF termCH=ESC THEN
- WriteString("<ESC>"); Aborted:= TRUE; WriteLn;
- ELSIF termCH=CAN THEN
- WriteString(" - cancelled"); WriteLn; Wait; Aborted:=FALSE;
- ELSE
- Write(BEL); WriteString(" --- error occured: ");
- WriteString("tried to read past end of file");
- WriteLn; Aborted:=TRUE;
- END(*IF ESC*);
- ELSE
- Aborted:=FALSE; ch:=s[0];
- IF InChs(ch) THEN
- (*RETURN with ch*)
- ELSIF ch=HELP THEN curGiveHelp
- ELSE
- Write(BEL);
- WriteString(" --- out of range; press one of ");
- Write("'"); WriteString(chs); Write("'"); WriteLn; Wait;
- Done:=FALSE;
- END(*IF valid range*);
- END(*IF not eof*);
- UNTIL Done OR Aborted;
- curGiveHelp:=DefaultGiveHelp;
- END PromptForChars;
-
-
- PROCEDURE PromptForInt(p: ARRAY OF CHAR; min,max: INTEGER; VAR x: INTEGER);
- BEGIN (*PromptForInt*)
- REPEAT
- WriteString(p);
- (* random screen not supported: epr:=Row; epc:=Col; ScrollUps:=0; *)
- ReadInt(x);
- IF NOT Done THEN
- IF termCH=ESC THEN
- WriteString("<ESC>"); Aborted:= TRUE; WriteLn;
- ELSIF termCH=CAN THEN
- WriteString(" - cancelled"); WriteLn; Wait;
- ELSIF termCH=HELP THEN
- curGiveHelp
- ELSE
- Write(BEL); WriteString(" --- illegal number; enter INTEGER");
- WriteLn; Wait;
- END(*IF ESC*);
- ELSE
- Aborted:=FALSE;
- IF (min<=x) AND (x<=max) THEN
- (*RETURN with x*)
- ELSE
- Write(BEL);
- WriteString(" --- out of range; enter number within ");
- WriteInt(min,0); WriteString(".."); WriteInt(max,0); WriteLn;
- Wait; Done:=FALSE;
- END(*IF valid range*);
- END(*IF legal INTEGER*);
- UNTIL Done OR Aborted;
- curGiveHelp:=DefaultGiveHelp;
- END PromptForInt;
-
- PROCEDURE PromptForReal(p: ARRAY OF CHAR; min,max: REAL; VAR x: REAL);
- BEGIN (*PromptForReal*)
- REPEAT
- WriteString(p);
- (* random screen not supported: epr:=Row; epc:=Col; ScrollUps:=0; *)
- ReadReal(x);
- IF NOT Done THEN
- IF termCH=ESC THEN
- WriteString("<ESC>"); Aborted:= TRUE; WriteLn;
- ELSIF termCH=CAN THEN
- WriteString(" - cancelled"); WriteLn; Wait;
- ELSIF termCH=HELP THEN
- curGiveHelp
- ELSE
- Write(BEL); WriteString(" --- illegal number; enter REAL");
- WriteLn; Wait;
- END(*IF ESC*);
- ELSE (*Done=TRUE*)
- Aborted:=FALSE;
- IF (min<=x) AND (x<=max) THEN
- (*RETURN with x*)
- ELSE
- Write(BEL);
- WriteString(" --- out of range; enter number within ");
- WriteReal(min,0,5); WriteString(".."); WriteReal(max,0,5); WriteLn;
- Wait; Done:=FALSE;
- END(*IF valid range*);
- END(*IF legal REAL*);
- UNTIL Done OR Aborted;
- curGiveHelp:=DefaultGiveHelp;
- END PromptForReal;
-
- PROCEDURE InstallReadProc (rp: ReadProc);
- BEGIN
- curRP := rp;
- END InstallReadProc;
-
- PROCEDURE InstallWriteProc (wp: WriteProc);
- BEGIN
- curWP := wp;
- END InstallWriteProc;
-
- PROCEDURE InstallWriteLnProc (wlnp: WriteLnProc);
- BEGIN
- curWLnP := wlnp
- END InstallWriteLnProc;
-
-
- BEGIN
- termCH:= " "; Done:=FALSE; Aborted:=FALSE;
- yes:="YES"; no:="NO ";
- curRP := Terminal.Read;
- curWP := Terminal.Write;
- curWLnP := Terminal.WriteLn;
- curGiveHelp:=DefaultGiveHelp;
- (* no random, i.e. cursor controlled, screen output
- supported in current implementation: *)
- RandomWriteDisplay := FALSE;
- END HighInOut .
-